﻿using System.Collections.Generic;
using System.IO;
using System.Web;
using System.Web.Script.Serialization;
using MongoDB.Bson;
using MongoDB.Driver.Builders;
using MongoDB.Driver.GridFS;
using MongoDB.Driver.Linq;
using PicShare.Data;
using PicShare.Server.Attributes;
using PicShare.Server.Helpers;
using PicShare.Server.Models;
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.ValueProviders;
using PicShare.Server.Repositories;
using ServiceStack.Common.Utils;

namespace PicShare.Server.Controllers
{
    public class UsersController : BaseApiController
    {

        private readonly IRepository<User> _repository;

        public UsersController(IRepository<User> repository)
        {
            this._repository = repository;
        }

        [ActionName("clear")]
        public string GetClearDatabse()
        {
            _repository.Clear();
            return "Cleared";
        }

        #region User ---> Login Register Logout
        [ActionName("register")]
        public HttpResponseMessage PostRegisterUser(User model)
        {
            var responseMesg = this.PerformOperationAndHandleExceptions(
             () =>
             {
                 LoginRegisterHelper.ValidateUserName(model.UserName);
                 LoginRegisterHelper.ValidateAuthCode(model.AuthCode);

                 var usersList = _repository.GetAll();

                 var usernameToLower = model.UserName.ToLower();

                 object existingUser = null;

                 if (usersList.Count() != 0)
                 {
                     existingUser = _repository.Find(usr => usr.UserName == model.UserName);
                 }

                 if (existingUser != null)
                 {
                     throw new InvalidOperationException("User exists");
                 }

                 var user = new User()
                  {
                      UserName = model.UserName,
                      AuthCode = model.AuthCode,
                  };

                 _repository.Add(user);

                 var registeredUser = _repository.Find(usr => usr.Id == user.Id);

                 model.SessionKey = LoginRegisterHelper.GenerateSessionKey(user.Id.ToString());

                 var userWhithSessionKey = new User()
                 {
                     Id = registeredUser.Id,
                     UserName = registeredUser.UserName,
                     AuthCode = registeredUser.AuthCode,
                     SessionKey = model.SessionKey
                 };

                 var returnedUser = _repository.Update(userWhithSessionKey);

                 var response = this.Request.CreateResponse(HttpStatusCode.Created, userWhithSessionKey);
                 return response;
             });

            return responseMesg;
        }

        [ActionName("logout")]
        public HttpResponseMessage PutLogoutUser([ValueProvider(typeof(HeaderValueProviderFactory<string>))]
            string sessionKey)
        {
            var responseMesg = this.PerformOperationAndHandleExceptions(
             () =>
             {
                 var user = _repository.Find(usr => usr.SessionKey == sessionKey);

                 HttpResponseMessage response = null;

                 if (user != null)
                 {
                     user.SessionKey = null;
                     _repository.Update(user);
                     response = this.Request.CreateResponse(HttpStatusCode.OK, "User Logged Out");
                 }
                 else
                 {
                     response = this.Request.CreateErrorResponse(HttpStatusCode.NotModified, "User Did Not Logged Out");
                 }
                 return response;
             });

            return responseMesg;
        }

        [ActionName("login")]
        public HttpResponseMessage PostLogoutUser(LoginUserModel user)
        {
            var responseMesg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var usersList = _repository.GetAll();

                    var searchedUser = usersList.FirstOrDefault(
                        usr => usr.AuthCode == user.AuthCode
                               && usr.UserName == user.UserName);

                    HttpResponseMessage response = null;

                    if (searchedUser != null)
                    {
                        var loggedUser = new LoginReturnModel()
                        {
                            Id = searchedUser.Id,
                            UserName = searchedUser.UserName,
                            AuthCode = searchedUser.AuthCode,
                            SessionKey = LoginRegisterHelper.GenerateSessionKey(searchedUser.Id.ToString())
                        };

                        if (searchedUser.Albums != null)
                        {
                            var albums = (from alb in searchedUser.Albums
                                select alb.Key
                                ).ToList();
                            loggedUser.AlbumNames = albums;
                        }
                        else
                        {
                            loggedUser.AlbumNames = null;
                        }

                        searchedUser.SessionKey = loggedUser.SessionKey;
                        _repository.Update(searchedUser);
                        response = this.Request.CreateResponse(HttpStatusCode.OK, loggedUser);
                    }
                    else
                    {
                        response = this.Request.CreateErrorResponse(HttpStatusCode.NotModified, "Wrong Data Presented");
                    }
                    return response;
                });
            return responseMesg;
        }


        #endregion

        #region User ---> User Information

        [ActionName("change-password")]
        public HttpResponseMessage PutChangeUserPassword([ValueProvider(typeof(HeaderValueProviderFactory<string>))]
            string sessionKey, ChangePasswordModel passwordModel)
        {/*
            var responseMesg = this.PerformOperationAndHandleExceptions(
             () =>
             {
                 HttpResponseMessage response = null;
                 LoginRegisterHelper.ValidateAuthCode(passwordModel.NewPassword);
                 var user = _repository.ChangePasswordModel(sessionKey, passwordModel);

                 if (user != null)
                 {
                     response = this.Request.CreateResponse(HttpStatusCode.OK, "Password Changed");
                 }
                 else
                 {
                     response = this.Request.CreateErrorResponse(HttpStatusCode.NotModified, "An Error");
                 }
                 return response;
             });

            return responseMesg;
          */
            return null;
        }


        #endregion

    }
}
